/* eslint-disable no-unused-vars */
import React, { useState, useEffect, useRef } from 'react';
import { Modal, Form, Input, Select, DatePicker, Switch, Radio, message } from 'antd';
import { Link } from 'react-router-dom';
import PropTypes from 'prop-types';
import {
  CIDR_RE,
  IP_INTERVAL_RE,
  IP_RE,
  IP_V6,
  DOMAIN_RE,
  FULL_URL_RE,
  ENG_NAME,
  IP_V6_CIDR
} from '@util/constants';
// import { setRouteInfo } from '@api/networkConfig';
import { connect } from 'react-redux';
import { addUser, updateUser, getStaffList } from '@api/user';
import rsa from '@util/rsa';
import moment from 'moment';
import { _ } from 'core-js';
import './index.less';

function useDidUpdateEffect(fn, inputs) {
  const didMountRef = useRef(false);
  useEffect(() => {
    if (didMountRef.current) {
      fn();
    } else {
      didMountRef.current = true;
    }
  }, inputs);
}

const formItemLayout = {
  labelCol: {
    span: 4
  },
  wrapperCol: {
    span: 16
  }
};
const { TextArea } = Input;
function EditModal(props) {
  const { form, visible, edit, roles, detail = {}, disabledkey = {}, onSuccess, Rkey } = props;
  const { getFieldDecorator, validateFields, setFieldsValue, resetFields } = form;
  const [loading] = useState(false);
  const [staffPagination, setStaffPagination] = useState({
    page: 1,
    pageSize: 10
  });
  const [paginationCount, sePaginationCount] = useState(0);
  const [staffScreachList, setStaffScreachList] = useState([]);
  const [siteRanges, setSiteRanges] = useState('');
  const [selectLoading, setSelectLoading] = useState(false);
  const [ipsError, setIpError] = useState();
  const [showEmile, setShowEmile] = useState();
  const CIDRCountList = new Array(16).fill(1).map((item, index) => {
    return Math.pow(2, index);
  });

  const loadStafflist = data => {
    const { page, pageSize, search } = data;
    setSelectLoading(true);
    getStaffList({ page, pageSize, search })
      .then(res => {
        const stafflist = _.get(res, 'data.data.list', []);
        let list = staffScreachList.concat(stafflist);
        setStaffScreachList(list);
        sePaginationCount(_.get(res, 'data.data.count', 0));
      })
      .finally(() => {
        setSelectLoading(false);
      });
  };

  useEffect(() => {
    if (!visible) {
      resetFields();
      // 关闭弹窗重制数据
      setStaffScreachList([]);
      setShowEmile(false);
      setStaffPagination({ page: 1, pageSize: 10 });
      return;
    }
    if (visible) {
      if (staffScreachList.length === 0) {
        loadStafflist({ page: 1, pageSize: 10, search: '' });
      }
    }
    if (detail.isDefaultRole && detail.nickname === '安全管理员') {
      setShowEmile(true);
      // 处理异步问题需要优化
      setTimeout(() => {
        setFieldsValue({ email: detail.email });
      });
      return;
    }
    // 不是为组织管理跳转
    if (!Rkey) {
      if (detail.expired) {
        detail.expired = moment(detail.expired, 'YYYY-MM-DD HH:mm:ss');
      }
      let staff = _.get(detail, 'staffOid', {});
      if (!staff) {
        return;
      }
      let Ndetail = {
        username: detail.username,
        staffOid: [staff.nickname, staff.email, staff.telephone].filter(Boolean).join('/'),

        role_id: _.get(detail, 'role_oid._id', ''),
        expired: detail.expired,
        enable: _.get(detail, 'enable', true)
      };
      setShowEmile(false);
      setSiteRanges(_.get(detail, 'siteRangeOid.siteRanges', []));
      // 处理异步问题需要优化
      setTimeout(() => {
        setFieldsValue({ openSiteRange: detail.openSiteRange });
      }, 300);
      setTimeout(() => {
        setFieldsValue(Ndetail);
      });
    }
  }, [visible]);

  useEffect(() => {
    // 判断是否为组织管理跳转
    let username = () => {
      if (detail.username) {
        return detail.username;
      }
      if (_.get(detail, 'userInfo.nickname', '')) {
        return _.get(detail, 'userInfo.nickname', '');
      }
      if (detail.email) {
        return detail.email.split('@')[0];
      }
    };
    if (Rkey) {
      setFieldsValue({
        staffOid: [detail.nickname, detail.email, detail.telephone].filter(Boolean).join('/'),
        username: username(),

        role_id: _.get(detail, 'userInfo.role_oid._id', ''),
        expired: _.get(detail, 'userInfo.expired', '')
          ? moment(_.get(detail, 'userInfo.expired', ''), 'YYYY-MM-DD HH:mm:ss')
          : null,
        enable: _.get(detail, 'userInfo.enable', true)
      });
      let siteRanges = _.get(detail, 'userInfo.siteRangeOid.siteRanges', []);
      setSiteRanges(siteRanges);
      setFieldsValue({ openSiteRange: siteRanges.length > 0 });
    }
  }, [detail]);
  // 重制
  const onReset = () => {
    form.resetFields();
  };
  const onCancel = () => {
    setIpError();
    onReset();
    props.onCancel();
  };

  const scrollEnd = e => {
    const { target } = e;
    e.persist();
    // 滚动 触底 看接口是否还有剩余的值没传过来
    if (target.scrollTop + target.offsetHeight + 1 >= target.scrollHeight) {
      const { page, pageSize } = staffPagination;
      if (page * pageSize < paginationCount) {
        setStaffPagination({
          ...staffPagination,
          page: page + 1
        });
      }
    }
  };

  const onOk = () => {
    return validateFields(async (err, values) => {
      const RkeyEdit = ['安全操作员', '安全管理员', '操作员'];
      let add = !RkeyEdit.includes(Rkey) && !edit;
      const desc = !add ? '编辑' : '添加';
      const todo = !add ? updateUser : addUser;
      if (!err) {
        if (values.openSiteRange && siteRanges.length === 0) {
          setIpError('自定义资产范围为必填');
          return;
        }
        if (ipsError) {
          return;
        }
        if (values.expired) {
          values.expired = moment(values.expired).format('YYYY-MM-DD 23:59:59');
        } else {
          delete values.expired;
        }
        if (detail._id && Rkey !== '未开通') {
          if (detail.userOid) {
            values['user_id'] = detail.userOid;
          } else {
            values['user_id'] = detail._id;
          }
          delete values.username;
        } else {
          values['publicKey'] = rsa.getKeys('local').public;
        }
        // 修改并且不是修改的安全管理员
        if (edit && !detail.isDefaultRole) {
          values.staffOid = detail.staffOid._id;
        } else if (Rkey) {
          values.staffOid = detail._id;
        }
        if (siteRanges) {
          values.siteRanges = siteRanges;
        }
        // 如果是默认安全管理员单独处理role_oid
        if (detail.isDefaultRole && detail.nickname === '安全管理员') {
          values.role_id = detail.role_id;
          delete values.staffOid;
        }
        todo({ ...values })
          .then(res => {
            const password = _.get(res, 'data.data.password');
            const decryptedPassword = password
              ? rsa.decrypt(password, rsa.getKeys('local').private)
              : '';
            if (typeof onSuccess === 'function') {
              onSuccess(
                decryptedPassword,
                // eslint-disable-next-line no-undefined
                (['未开通'].includes(Rkey) || !Rkey) && typeof edit !== undefined && !edit
              );
              onReset();
            }
            message.success(`${desc}成功`);
          })
          .catch(error => {
            if (error && error.type === 'parsed') {
              return message.error(`${desc}用户失败:${error.message}`);
            }
            message.error(`${desc}用户失败`);
          })
          .finally(() => {});
      }
    });
  };
  const onSearch = e => {
    setStaffScreachList([]);
    setStaffPagination({ ...staffPagination, search: e, page: 1 });
  };

  useDidUpdateEffect(() => {
    if (staffPagination.page) {
      loadStafflist(staffPagination);
    }
  }, [staffPagination.page]);

  useDidUpdateEffect(() => {
    if (staffPagination.search) {
      loadStafflist({ page: 1, pageSize: 10, search: staffPagination.search });
    } else {
      loadStafflist({ page: 1, pageSize: 10, search: '' });
    }
  }, [staffPagination.search]);
  const onTargetsChange = e => {
    const value = e.target.value;
    const targets = _.split(value, '\n');
    let ipsError = value.length ? '' : '探测目标不能为空';
    setSiteRanges(Array.isArray(targets) ? targets : [targets]);
    let targetCount = 0;

    for (let i = 0; i < targets.length; i++) {
      const target = targets[i];
      if (
        DOMAIN_RE.test(target) ||
        IP_RE.test(target) ||
        IP_V6.test(target) ||
        FULL_URL_RE.test(target) ||
        IP_V6_CIDR.test(target)
      ) {
        targetCount += 1;
      } else if (CIDR_RE.test(target)) {
        const range = target.split('/')[1];
        if (Number(range) < 16) {
          targetCount = Infinity;
          break;
        } else {
          targetCount += CIDRCountList[Number(range)];
        }
      } else if (IP_INTERVAL_RE.test(target, true)) {
        const ipRange = target.split('-');
        const startIPArr = ipRange[0].split('.').map(Number);
        const endIPArr = ipRange[1].split('.').map(Number);
        if (startIPArr[0] !== endIPArr[0] || endIPArr[1] !== startIPArr[1]) {
          targetCount = Infinity;
          ipsError = '起始IP和末尾IP只允许最后两位不同';
          break;
        }
        const rangeC = endIPArr[2] - startIPArr[2];
        const rangeD = endIPArr[3] - startIPArr[3];
        const ipCount = rangeC * Math.pow(2, 8) + rangeD;
        if (ipCount <= 0) {
          ipsError = '起始IP必须小于末尾IP';
          break;
        } else {
          targetCount += ipCount;
        }
      } else {
        ipsError = '探测目标格式错误';
        break;
      }
    }
    setIpError(ipsError);
  };

  useEffect(() => {
    if (staffPagination.search) {
      if (staffScreachList.length === 0) {
        props.form.setFields({
          staffOid: {
            value: '',
            errors: [new Error('未搜索到对应人员，请点击"添加人员"在组织中添加该人员')]
          }
        });
      } else {
        props.form.setFields({
          staffOid: {
            value: '',
            errors: false
          }
        });
      }
    }
  }, [staffScreachList]);

  const disabledDate = current => {
    return current && current < moment().startOf('day');
  };

  const filteredRoles = roles.filter(
    i => i && !i.is_admin && !['系统管理员', '审计员'].includes(i.name)
  );
  const findId = name => filteredRoles.find(r => r.name === name);
  // eslint-disable-next-line no-undefined
  let visibleEdit = (['未开通'].includes(Rkey) || !Rkey) && typeof edit !== undefined && !edit;
  const staffOidChange = e => {
    const setArr = staffScreachList.filter(item => {
      return item._id === e;
    });
    if (setArr[0] && setArr[0].email) {
      const str = setArr[0].email.split('@')[0];
      setFieldsValue({ username: str });
    }
    return e;
  };
  const validatorToUsername = (rule, value, callback) => {
    let error = '';
    const re = new RegExp(ENG_NAME);
    const errorDist = {
      [!re.test(value)]: () => {
        return '用户名不能为中文和空格';
      },
      [value && value.length > 128]: () => {
        return '用户名长度最大为128';
      },
      [value && value.length < 2]: () => {
        return '用户名长度最小为2';
      },
      [!value]: () => {
        return '用户名不能为空';
      }
    };
    callback(errorDist[true]);
  };
  return (
    <>
      <Modal
        title={visibleEdit ? '添加用户' : '编辑用户'}
        {...props}
        onOk={onOk}
        onCancel={onCancel}
        width={580}
        loading={loading}
        className="add-user-manage"
      >
        <Form labelAlign="left" initialValues={{ openSiteRange: false }}>
          {!showEmile ? (
            <>
              <Form.Item {...formItemLayout} label="关联人员" colon={false}>
                {getFieldDecorator('staffOid', {
                  rules: [
                    {
                      required: true,
                      message: '请按姓名或邮箱地址进行搜索'
                    }
                  ],
                  validateFirst: true,
                  getValueFromEvent: staffOidChange
                })(
                  <Select
                    showSearch
                    disabled={disabledkey.staffOid || edit}
                    placeholder="请输入管理员"
                    defaultActiveFirstOption={false}
                    showArrow={false}
                    filterOption={false}
                    notFoundContent={null}
                    onSearch={onSearch}
                    loading={selectLoading}
                    dropdownRender={menu =>
                      staffScreachList.length !== 0 ? (
                        <>
                          <p style={{ padding: 10, marginBottom: -10, fontWeight: 800 }}>
                            所有用户({paginationCount})
                          </p>
                          {menu}
                        </>
                      ) : (
                        <></>
                      )
                    }
                    onPopupScroll={scrollEnd}
                  >
                    {staffScreachList.map(staff => (
                      <Select.Option key={staff._id} disabled={staff.userOid}>
                        <p style={{ display: 'flex', justifyContent: 'space-between' }}>
                          <p
                            style={{ maxWidth: 300, overflow: 'hidden', textOverflow: 'ellipsis' }}
                          >
                            {[staff.nickname, staff.email, staff.telephone]
                              .filter(Boolean)
                              .join('/')}
                          </p>
                          {staff.userOid ? (
                            <span style={{ float: 'right' }}>已有用户账号</span>
                          ) : null}
                        </p>
                      </Select.Option>
                    ))}
                  </Select>
                )}
                <Link to="/asset-config/organization?openModel" className="addUser">
                  添加人员
                </Link>
              </Form.Item>
              <Form.Item {...formItemLayout} label="用户名" colon={false}>
                {getFieldDecorator('username', {
                  rules: [
                    {
                      required: true,
                      validator: validatorToUsername
                    }
                  ]
                })(
                  <Input
                    disabled={disabledkey.username || edit}
                    placeholder="请输入英文、数字或特殊符号，长度2-128位用户名"
                  />
                )}
              </Form.Item>
              <Form.Item {...formItemLayout} label={'失效日期'} colon={false}>
                {getFieldDecorator('expired')(
                  <DatePicker disabledDate={disabledDate} style={{ width: '100%' }} />
                )}
              </Form.Item>
              <Form.Item {...formItemLayout} label="用户角色" colon={false}>
                {getFieldDecorator('role_id', {
                  rules: [
                    {
                      required: true,
                      message: '请选择用户角色'
                    }
                  ]
                })(
                  <Select
                    onChange={() => {
                      setTimeout(() => {
                        setFieldsValue({ openSiteRange: false });
                      }, 100);
                    }}
                  >
                    {filteredRoles.map(role => {
                      const { _id, name } = role;
                      const option = (
                        <Select.Option key={_id} value={_id}>
                          {name}
                        </Select.Option>
                      );
                      return option;
                    })}
                  </Select>
                )}
              </Form.Item>
              {form.getFieldValue('role_id') === _.get(findId('安全操作员'), '_id') ? (
                <Form.Item {...formItemLayout} label="资产管理范围" colon={false}>
                  {getFieldDecorator('openSiteRange', {
                    rules: [
                      {
                        required: true,
                        message: '请选择管理范围'
                      }
                    ]
                  })(
                    <Radio.Group>
                      <Radio value={true}>自定义资产范围</Radio>
                      <Radio value={false}>不限制任何资产</Radio>
                    </Radio.Group>
                  )}
                  {form.getFieldValue('openSiteRange') && (
                    <>
                      <span className="require-tip">*</span>
                      <TextArea
                        autosize={{ minRows: 5, maxRows: 5 }}
                        value={_.join(siteRanges, '\n')}
                        rows={5}
                        onChange={onTargetsChange}
                        placeholder={
                          '支持IPv4、IPv6、IPv4段、IPv6段、域名、URL，多个目标请用换行符分隔，如\n192.168.1.1\n2001:DB8:0:0:8:800:200C:417A\n192.168.1.1-192.168.255.25(最大到一个B段)\n11::11:00/118(最大支持1024个IPv6地址)\n192.168.1.0/24\nwww.example.com\nhttp://www.example.com'
                        }
                      />
                      {<p className="validate-error">{ipsError}</p>}
                    </>
                  )}
                </Form.Item>
              ) : null}
              <Form.Item {...formItemLayout} colon={false} label="是否启用">
                {getFieldDecorator('enable', { valuePropName: 'checked' })(<Switch />)}
              </Form.Item>
            </>
          ) : null}
          {showEmile ? (
            <Form.Item {...formItemLayout} label="邮箱" colon={false}>
              {getFieldDecorator('email', {
                rules: [
                  {
                    required: true,
                    message: '请输入邮箱账户'
                  }
                ],
                validateFirst: true
              })(<Input />)}
            </Form.Item>
          ) : null}
        </Form>
      </Modal>
    </>
  );
}
EditModal.propTypes = {
  edit: PropTypes.bool,
  visible: PropTypes.bool,
  onOk: PropTypes.func,
  modalType: PropTypes.string,
  onCancel: PropTypes.func,
  netWorkTableData: PropTypes.array,
  form: PropTypes,
  roles: PropTypes.array,
  password: PropTypes.string,
  statusModalVisble: PropTypes.bool,
  detail: PropTypes,
  disabledkey: PropTypes.object,
  onSuccess: PropTypes.func,
  Rkey: PropTypes.string
};

const mapStateToProps = state => {
  return {
    roles: _.get(state, 'role.roles', [])
  };
};

export default connect(mapStateToProps, null)(Form.create()(EditModal));
